<?php

namespace App\Repository\Service;

use App\Models\Admin\AdminUsers;
use App\Models\Dept;
use App\Models\Orders\OrdersModel;
use App\Models\Orders\OrdersUserModel;
use App\Models\Service\ServiceModel;
use App\Repository\BaseRepository;
use App\Repository\Commit\DictDatarRepository;
use Illuminate\Support\Facades\Cache;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;

class ServiceRepository extends BaseRepository
{
    public $model;
    public $log;

    public function __construct()
    {
        $this->model = new ServiceModel();
        $this->log = new Logger('service');
        $this->log->pushHandler(
            (new RotatingFileHandler(storage_path('/logs/service.log'), 14, Logger::DEBUG, true, 0777))->setFormatter(new LineFormatter(null, null, true, true))
        );
        parent::__construct();
    }

//    客服人员分配报表
    public function loadAssignUsersReport($params)
    {
        $data = $this->assignServiceOptionsList($params['user'], ['b.id', 'b.nick_name']);
        $services = [];
        $select = [];
        foreach ($data['data'] as $k => $v) {
            $services[$v['id']] = $v['nick_name'];
            $select[] = 'SUM(if(service_user_id = ' . $v['id'] . ',1,0)) as ' . 'total' . $v['id'];
        }
        $where = [];
        if (isset($params['dateRange']) && !empty($params['dateRange']) && is_array($params['dateRange'])) {
            $params['dateRange'] = [date('Y-m-d', strtotime($params['dateRange'][0])), date('Y-m-d', strtotime($params['dateRange'][1])) . ' 23:59:59'];
            $where['between']['created_at'] = $params['dateRange'];
        }
        $ModelOrders = new OrdersModel();
        //        加载具体订单
        if (isset($params['service_id']) && $params['service_id'] > 0) {
            $where['eq']['service_user_id'] = $params['service_id'];

            $fields = ['id', 'ordersno', 'created_at', 'goods_name', 'product_name', 'iccid'];
            $page = $params['pageNum'] ?? 1;
            $limit = $params['pageSize'] ?? 10;
            $total = 0;
            if ($page <= 1) {
                $total = $ModelOrders->searchWhere($where)->count('id');
            }
            $rows = $ModelOrders->select($fields)->searchWhere($where)->page($page, $limit)->get();
            return $this->returnMsg(200, '数据已查询', $rows, $total);
        }
        //        不用in,慢
        $where['gt']['service_user_id'] = 0;
        $row = $ModelOrders->selectRaw(implode(',', $select))->searchWhere($where)->first();
        $result = [];
        foreach ($services as $serviceId => $name) {
            $total = 0;
            if (isset($row['total' . $serviceId])) {
                $total = $row['total' . $serviceId];
            }
            $result[] = [
                'service_id' => $serviceId,
                'service_name' => $name,
                'total' => $total
            ];
        }
        unset($row, $data);
        return $this->returnMsg(200, '数据已查询', $result);
    }

//客服组人员
    public function loadServiceUsers($loginUser)
    {
        return $this->assignServiceOptionsList($loginUser, ['b.id', 'b.nick_name', 'b.online', 'b.update_time']);
    }

    public function updateServiceUsers($params)
    {
        $ModelUsers = new AdminUsers();
        $where = [];
        if (empty($params['id'])) {
            return $this->returnMsg(1, '请指明账号');
        }
        if (!isset($params['online'])) {
            return $this->returnMsg(1, '请指明在线状态');
        }
        $where['eq']['shop_id'] = $params['user']['shop_id'];
        if (is_array($params['id'])) {
            if (count($params['id']) == 1) {
                $where['eq']['id'] = $params['id'];
            } else {
                $where['in']['id'] = $params['id'];
            }
        } else {
            $where['eq']['id'] = $params['id'];
        }
        $status = intval($params['online']);
        $ModelUsers->searchWhere($where)->update(['online' => $status]);
        return $this->returnMsg(200, '操作成功');
    }

//    返回一条新的没客服的订单给前端
    public function robNotification()
    {
        $ModelOrders = new OrdersModel();
        $where = [
            'service_user_id' => 0
        ];
        $row = $ModelOrders->where($where)->select(['id', 'ordersno', 'goods_name'])->inRandomOrder()->first();
        if (empty($row)) {
            return $this->returnMsg(1, '没单了');
        }
        return $this->returnMsg(200, '有单抢啦!', $row, 1);
    }

//分配客服的时候拉客服信息
    public function assignServiceOptionsList($loginUser, $fields = null)
    {
        $ModelDept = new Dept();
        $ModelUsers = new AdminUsers();
        $where = [];
        $where['where']['a.dept_name'] = '客服部';
        $where['where']['a.status'] = 0;
        $where['where']['a.del_flag'] = 0;
        $where['where']['a.shop_id'] = $loginUser['shop_id'];
        $where['where']['b.del_flag'] = 0;
        if (empty($fields)) {
            $fields = ['b.id', 'b.nick_name'];
        }
        $rows = $ModelDept->from($ModelDept->getTable(), 'a')
            ->leftJoin($ModelUsers->getTable() . ' AS b', 'b.dept_id', '=', 'a.dept_id')
            ->select($fields)
            ->searchWhere($where)
            ->get();
        if (empty($rows)) {
            return $this->returnMsg(1, '客服部没有客服,请创建名为:客服部的部门,然后增加人员到[客服部]');
        }
        return $this->returnMsg(200, '查询完毕', $rows);
    }

    //列表抢单
    public function index($request, $page = 1, $limit = 10)
    {
        $ModelOrdersUser = new OrdersUserModel();
        $ModelOrders = new OrdersModel();

        $OrdersTable = $ModelOrders->getTable();
        $OrdersUserTable = $ModelOrdersUser->getTable();
        //        查询条件
        $where = [];
        $where['where']['a.service_user_id'] = 0;
//        $time = $request['dateRange'];
//        $where['between'] = ['a.created_at' => [$time]];
        $rows = [];
        $fields = [];
        $aFields = $ModelOrders->getTableField();
//        排除不返回查询的字段
        $aExcept = [];
        $bFields = $ModelOrdersUser->getTableField();
        //        排除不返回查询的字段
        $bExcept = ['id', 'orderno', 'created_at', 'updated_at', 'remark'];
        foreach (array_diff($aFields, $aExcept) as $field) {
            $fields[] = 'a.' . $field;
        }
        foreach (array_diff($bFields, $bExcept) as $field) {
            $fields[] = 'b.' . $field;
        }
//        $fields = ['a.id', 'b.orderno'];
        //        关联查询数据
        $totalRows = $ModelOrders->from($OrdersTable, 'a')->count('a.id');
        //        再加上分页查询条件
        foreach ($ModelOrders->from($OrdersTable, 'a')
                     ->leftJoin($OrdersUserTable . ' AS b', 'b.id', '=', 'a.orders_user_id')
                     ->select($fields)
                     ->searchWhere($where)
                     ->page($page, $limit)
                     ->orderBy('a.id', 'desc')
                     ->cursor() as $row) {
            $rows[] = $row;
        }
//        echo $this->getLastSql();
        return $this->returnMsg(200, '查询成功', $rows, $totalRows);
    }

//    我的已接单工作订单列表
    public function workList($request, $page = 1, $limit = 10)
    {

        $ModelOrdersUser = new OrdersUserModel();
        $ModelOrders = new OrdersModel();
        $ServiceTable = $this->model->getTable();
        $OrdersTable = $ModelOrders->getTable();
        $OrdersUserTable = $ModelOrdersUser->getTable();
        //        查询条件
        $where = [];
        $where['where']['a.users_id'] = $request['user']['id'];
//        参照card.serviceWorkTypeList设置查询
        $searchType = intval($request['type']);
        switch ($searchType) {
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
                $where['where']['a.days'] = $searchType;
                break;
            case 40:
//                待跟进订单,有出物流单号的
                $where['notempty'][] = 'b.express_number';
                break;
            case 41:
//                待转化订单,没有出物流单号的失败单
                $where['eq']['a.days'] = 1;
//                $where['empty'][] = 'b.express_number';
                //                订单状态判断
                $where['eq']['b.status'] = 20;
                break;
            case 42:
//                跟进中订单,已跟进，打了外呼但没有激活
                $where['eq']['a.days'] = 1;
//                订单状态判断
                $where['eq']['b.status'] = 40;
                break;
            case 43:
//                已完结订单,用户已经充值了，算完结
                $where['eq']['b.first_status'] = 1;
                break;
            default:
//                新接的未处理过的单
                $where['wherenull'][] = 'a.updated_at';
                break;
        }
        $rows = [];
        $fields = [];
        $aFields = $this->model->getTableField();
//        排除不返回查询的字段
        $aExcept = ['orders_id', 'users_id', 'created_at', 'updated_at'];
        $bFields = $ModelOrders->getTableField();
//        排除不返回查询的字段
        $bExcept = ['id', 'nums'];
        foreach (array_diff($aFields, $aExcept) as $field) {
            $fields[] = 'a.' . $field;
        }
        foreach (array_diff($bFields, $bExcept) as $field) {
            $fields[] = 'b.' . $field;
        }
        foreach (['pay_name',
                     'pay_phone',
                     'pay_identity',
                     'post_province',
                     'post_city',
                     'post_area',
                     'post_address'] as $field) {
            $fields[] = 'c.' . $field;
        }
//        $fields = ['a.id', 'b.orderno'];
        //        关联查询数据
        $totalRows = $this->model->from($ServiceTable, 'a')
            ->leftJoin($OrdersTable . ' AS b', 'a.orders_id', '=', 'b.id')
            ->leftJoin($OrdersUserTable . ' AS c', 'b.orders_user_id', '=', 'c.id')
            ->searchWhere($where)->count('a.id');
//        echo $this->getLastSql();
        //        再加上分页查询条件
        foreach ($ModelOrders->from($ServiceTable, 'a')
                     ->leftJoin($OrdersTable . ' AS b', 'a.orders_id', '=', 'b.id')
                     ->leftJoin($OrdersUserTable . ' AS c', 'b.orders_user_id', '=', 'c.id')
                     ->select($fields)
                     ->searchWhere($where)
//                     ->orWhereNull('a.updated_at')
                     ->page($page, $limit)
                     ->cursor() as $row) {
            $rows[] = $row;
        }
//        echo $this->getLastSql();
        return $this->returnMsg(200, '查询成功', $rows, $totalRows);
    }

//修改分配错客服的客服归属
    public function editAssignService($userId, $serviceId, $ids)
    {
        $ModelOrders = new OrdersModel();
        $where = [];
        $where['gt']['service_user_id'] = 0;
        if (is_array($ids)) {
            $where['In']['id'] = $ids;
        } else {
            $where['where']['id'] = $ids;
        }
        if ($ModelOrders->searchWhere($where)->update(['service_user_id' => $serviceId])) {
            //  记录操作日志
            $ModelUsers = new AdminUsers();
            $serviceUserName = $ModelUsers->where(['id' => $serviceId])->value('nick_name');
            $LogsModel = new \App\Models\LogsModel();
            if (is_string($ids)) {
                $LogsModel->saveIt(0, $userId, $ids, "重新修改了订单归属:" . $serviceUserName);
            } else if (is_array($ids)) {
                $insertData = [];
                foreach ($ids as $k => $ordersId) {
                    $content = "重新修改了订单归属:" . $serviceId;
                    $insertData[] = [
                        'type' => 0,
                        'users_id' => $userId,
                        'table_id' => $ordersId,
                        'content' => $content
                    ];
                }
                if (!empty($insertData)) {
                    $LogsModel->insert($insertData);
                }
            }
            return $this->returnMsg(200, '已操作修改订单归属');
        }
        return $this->returnMsg(2, '修改失败');
    }

//分配操作
    public function receive($serviceId, $ids)
    {
        if (empty($ids)) {
            return $this->returnMsg(1, '请指明订单');
        }
        $ModelOrders = new OrdersModel();
        $where = [];
        $where['where']['service_user_id'] = 0;
        if (is_array($ids)) {
            if (count($ids) === 1) {
                $where['where']['id'] = $ids[0];
            } else {
                $where['In']['id'] = $ids;
            }
        } else {
            $where['where']['id'] = $ids;
        }
//       先查查询是为了防止别人先提交占了数据
        $rows = $ModelOrders->searchWhere($where)->select(['id', 'service_user_id'])->get()->toArray();
//        echo $this->getLastSql();
        if (empty($rows)) {
            return $this->returnMsg(2, '单已被其它人员抢走', $rows);
        }
        if (false !== $ModelOrders->searchWhere($where)->update(['service_user_id' => $serviceId])) {
//            保存订单信息给客服表
//            $inData = [];
//            foreach ($rows as $row) {
//                $inData[] = [
//                    'orders_id' => $row['id'],
//                    'users_id' => $userId,
//                ];
//            }
//            $this->model->insert($inData);
            return $this->returnMsg(200, '已操作订单归属', $rows);
        }
        return $this->returnMsg(2, '抢单失败');
    }

//    分配订单给客服,在OrdersRepository.php里调用
    public function randomBindServiceUser($ordersno, $contact_phone = '', $pay_identity = '')
    {
        $RepositoryDict = new DictDatarRepository();
        $serviceAssignType = $RepositoryDict->singleTypeValue('service_assign_type');
//        对应card.serviceAssignType
        if (intval($serviceAssignType) !== 2) {
            return $this->returnMsg(2, '设置非随机分配');
        }
        return $this->assignServiceBindOrders($ordersno, $contact_phone, $pay_identity);
    }

//状态分配,sku靓号提交失败后才调用
    public function statusBindServiceUser($ordersno, $contact_phone = '', $pay_identity = '')
    {
        $RepositoryDict = new DictDatarRepository();
        $serviceAssignType = $RepositoryDict->singleTypeValue('service_assign_type');
//        对应card.serviceAssignType
        if (intval($serviceAssignType) !== 1) {
//            $this->log->info('设置非状态分配');
            return $this->returnMsg(2, '设置非状态分配');
        }
        return $this->assignServiceBindOrders($ordersno, $contact_phone, $pay_identity);
    }

    public function assignServiceBindOrders($ordersno, $contact_phone = '', $pay_identity = '')
    {
        $ModelOrders = new OrdersModel();
        $ModelOrdersUser = new OrdersUserModel();
        $oldWhere = [];
        if (!empty($contact_phone) && !empty($pay_identity)) {
            $oldWhere['eq']['a.pay_identity'] = $pay_identity;
            $oldWhere['eq']['a.contact_phone'] = $contact_phone;
        } else {
            if (!empty($contact_phone)) {
                $oldWhere['eq']['a.contact_phone'] = $contact_phone;
            }
            if (!empty($pay_identity)) {
                $oldWhere['eq']['a.pay_identity'] = $pay_identity;
            }
        }
        //根据订单的phone与identity判断之前是否有已经分配过的客服了
        if (!empty($oldWhere)) {
            $oldWhere['egt']['b.service_user_id'] = 1;
            $row = $ModelOrdersUser->from($ModelOrdersUser->getTable(), 'a')
                ->leftJoin($ModelOrders->getTable() . ' AS b', 'b.ordersno', '=', 'a.orderno')
                ->select(['b.service_user_id'])
                ->searchWhere($oldWhere)
                ->first();
            $this->log->info($ordersno . '查旧归属:' . json_encode($oldWhere) . ';查出结果:' . json_encode($row));
//            使用原来的客服
            $serviceId = $row['service_user_id'] ?? 0;
            if ($serviceId > 0) {
                $ModelOrders->where(['ordersno' => $ordersno, 'service_user_id' => 0, 'sup_shop_id' => 0])->update(['service_user_id' => $serviceId]);
                return $this->returnMsg(200, '分配客服成功');
            }
        }
        unset($oldWhere);
//        新的分配方式开始,分给当前在线客服
        $RepositoryDict = new DictDatarRepository();
//        当前在线的客服
        $ModelDept = new Dept();
        $ModelUsers = new AdminUsers();
        $where = [];
        $where['where']['a.dept_name'] = '客服部';
        $where['where']['a.status'] = 0;
        $where['where']['a.del_flag'] = 0;
//        在线人员
        $where['where']['b.online'] = 1;
        $where['where']['b.del_flag'] = 0;
        $fields = ['b.id', 'b.online'];
        $rows = $ModelDept->from($ModelDept->getTable(), 'a')
            ->leftJoin($ModelUsers->getTable() . ' AS b', 'b.dept_id', '=', 'a.dept_id')
            ->select($fields)
            ->searchWhere($where)
            ->get()->toArray();
        if (empty($rows)) {
            $this->log->info('没有客服在线');
            return $this->returnMsg(2, '没有客服在线');
        }
        $cacheFile = config('card.serviceAssignTypeCacheFile');
        $cacheData = Cache::get($cacheFile);
        $today = date('Ymd');
        if (empty($cacheData)) {
            $cacheData = ['date' => 0];
        }
        if (!isset($cacheData['date'])) {
            $cacheData['date'] = 0;
        }
        $maxNums = $RepositoryDict->singleTypeValue('service_assign_max');
//        本次有没有没有达到最大分配数的客服
        $willAssignData = [];
        foreach ($rows as $k => $v) {
            //进入缓存,
            if (!isset($cacheData[$v['id']])) {
                $cacheData[$v['id']] = 0;
            }
            $hasAssignNums = $cacheData[$v['id']];
//            没有达到最大分配数
            if ($hasAssignNums < $maxNums) {
                $willAssignData[$v['id']] = $hasAssignNums;
            }
        }
        $this->log->info('maxNums:' . $maxNums . ';rows:' . json_encode($rows) . ';cacheData:' . json_encode($cacheData));
//        全部都大于限定,全部重新来,以天为单位,都归0
        if (empty($willAssignData) || $today != date('Ymd', $cacheData['date'])) {
            $cacheData = [];
            foreach ($rows as $k => $v) {
                $cacheData[$v['id']] = 0;
                $willAssignData[$v['id']] = 0;
            }
        }
//        这个值为空,可能出错,要返回
        if (empty($willAssignData)) {
            $this->log->info('willAssignData无数据');
            return $this->returnMsg(100, 'willAssignData无数据');
        }
//        按值升序,取第一个
        asort($willAssignData);
        $serviceId = key($willAssignData);
        if (empty($serviceId)) {
            $this->log->info('无客服id');
            return $this->returnMsg(100, '无客服id');
        }
        $this->log->info($ordersno . ';willAssignData:' . json_encode($willAssignData) . ';serviceId:' . $serviceId . ';cacheData:' . json_encode($cacheData));

//        分销商不用分配,只分配自己
        $res = $ModelOrders->where(['ordersno' => $ordersno, 'service_user_id' => 0, 'sup_shop_id' => 0])->update(['service_user_id' => $serviceId]);
        if (false !== $res) {
            $cacheData[$serviceId] = $cacheData[$serviceId] + 1;
            $cacheData['date'] = time();
            //        重新缓存数据
            Cache::put($cacheFile, $cacheData, 3600 * 24 * 30);
        }
        return $this->returnMsg(200, '分配客服成功');
    }
}
